home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume15 / ien116 < prev    next >
Encoding:
Internet Message Format  |  1988-06-07  |  24.3 KB

  1. Subject:  v15i050:  Updated IEN-116 namesever
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Jerry Aguirre <jerry@oliveb.atc.olivetti.com>
  7. Posting-number: Volume 15, Issue 50
  8. Archive-name: ien116
  9.  
  10. [  I used an earlier version in playing with some PC networking code
  11.    at my old job.  --r$  ]
  12.  
  13. This program implements the IEN 116 nameserver protocol.  A driver is
  14. provided, its first argument is the network name of the host running the
  15. nameserver, arguments 2-n are names to request the IP address of.  This
  16. program is of use primarily for Bridge terminal servers, many of which
  17. use this protocol in requesting machine addresses.  For further
  18. information, see the document itself.
  19.  
  20. #! /bin/sh
  21. # This is a shell archive, meaning:
  22. # 1. Remove everything above the #! /bin/sh line.
  23. # 2. Save the resulting text in a file.
  24. # 3. Execute the file with /bin/sh (not csh) to create the files:
  25. #    README
  26. #    nameserver.8
  27. #    Makefile
  28. #    ien116.h
  29. #    nameserver.c
  30. #    driver.c
  31. export PATH; PATH=/bin:$PATH
  32. echo shar: extracting "'README'" '(805 characters)'
  33. if test -f 'README'
  34. then
  35.     echo shar: will not over-write existing file "'README'"
  36. else
  37. sed 's/^X//' << \SHAR_EOF > 'README'
  38. XThis program implements the IEN 116 nameserver protocol.  A driver is
  39. Xprovided, its first argument is the network name of the host running the
  40. Xnameserver, arguments 2-n are names to request the IP address of.  This
  41. Xprogram is of use primarily for Bridge terminal servers, many of which
  42. Xuse this protocol in requesting machine addresses.  For further
  43. Xinformation, see the document itself.
  44. X
  45. XTo compile, the command:
  46. X    % make
  47. Xis sufficient.  This will build the nameserver and the driver.  The
  48. Xcommand:
  49. X    % make install
  50. Xwill install the nameserver daemon in /etc.  Start it by hand initially
  51. Xand then modify your rc.local file to run it at boot time.
  52. X
  53. XIt is only known that this works on a 4.3BSD Vax, but it is likely that
  54. Xit will function on any compatable UNIX(*) machine.
  55. X
  56. X(*) UNIX is a trademark of AT&T.
  57. SHAR_EOF
  58. if test 805 -ne "`wc -c < 'README'`"
  59. then
  60.     echo shar: error transmitting "'README'" '(should have been 805 characters)'
  61. fi
  62. fi # end of overwriting check
  63. echo shar: extracting "'nameserver.8'" '(702 characters)'
  64. if test -f 'nameserver.8'
  65. then
  66.     echo shar: will not over-write existing file "'nameserver.8'"
  67. else
  68. sed 's/^X//' << \SHAR_EOF > 'nameserver.8'
  69. X.TH nameserver 8 "Local \- June 24, 1987" "M. I. Bushnell"
  70. X.SH NAME
  71. Xnameserver \- process IEN 116 requests
  72. X.SH SYNOPSIS
  73. X.B nameserver
  74. X.SH DESCRIPTION
  75. X\fBNameserver\fR processes requests for network addresses using the IEN 116
  76. Xprotocol.
  77. X.SH SEE ALSO
  78. XIEN 116 \- Internet Name Server (J. Postel)
  79. X.SH DIAGNOSTICS
  80. XVarious messages logged by syslog using LOG_CRIT and LOG_ERR.
  81. XMainly self-explanatory.  Errors such as
  82. X.RS .5i
  83. XError sending error \fIn\fR: ....
  84. X.RE
  85. Xrefer to errors in the transmission of error messages back to the requestor.
  86. XFor explanation of the numbers, see the source.
  87. X.SH BUGS
  88. XWill not properly detach from the terminal if the terminal is opened on
  89. Xany descriptor other than 0, 1, or 2.
  90. SHAR_EOF
  91. if test 702 -ne "`wc -c < 'nameserver.8'`"
  92. then
  93.     echo shar: error transmitting "'nameserver.8'" '(should have been 702 characters)'
  94. fi
  95. fi # end of overwriting check
  96. echo shar: extracting "'Makefile'" '(352 characters)'
  97. if test -f 'Makefile'
  98. then
  99.     echo shar: will not over-write existing file "'Makefile'"
  100. else
  101. sed 's/^X//' << \SHAR_EOF > 'Makefile'
  102. X# Makefile for the IEN116 datagram server.
  103. X
  104. XCFLAGS=-O
  105. X
  106. Xall: nameserver driver
  107. X
  108. Xnameserver: nameserver.c
  109. X    $(CC) $(CFLAGS) -o nameserver nameserver.c
  110. X
  111. Xdriver: driver.c
  112. X    $(CC) $(CFLAGS) -o driver driver.c
  113. X
  114. X# installer needs write access to /etc/nameserver (root)
  115. Xinstall: /etc/nameserver
  116. X/etc/nameserver: nameserver
  117. X    install -c nameserver /etc/nameserver
  118. SHAR_EOF
  119. if test 352 -ne "`wc -c < 'Makefile'`"
  120. then
  121.     echo shar: error transmitting "'Makefile'" '(should have been 352 characters)'
  122. fi
  123. fi # end of overwriting check
  124. echo shar: extracting "'ien116.h'" '(393 characters)'
  125. if test -f 'ien116.h'
  126. then
  127.     echo shar: will not over-write existing file "'ien116.h'"
  128. else
  129. sed 's/^X//' << \SHAR_EOF > 'ien116.h'
  130. X/* defines for the ien116 name server */
  131. X
  132. X#define PORT 42            /* Port for the server */
  133. X
  134. X/* Message types from IEN 116 */
  135. X#define ADDR_REQ 1        /* Address Request */
  136. X#define ADDR_ANS 2        /* Address Request Answer */
  137. X#define ERR      3        /* Error */
  138. X
  139. X/* Error types from IEN 116 */
  140. X#define UNK_ERR  0        /* Unknown Error */
  141. X#define HOST_UNK 1        /* Host Unknown */
  142. X#define SYNT_ERR 2        /* Syntax Error */
  143. SHAR_EOF
  144. if test 393 -ne "`wc -c < 'ien116.h'`"
  145. then
  146.     echo shar: error transmitting "'ien116.h'" '(should have been 393 characters)'
  147. fi
  148. fi # end of overwriting check
  149. echo shar: extracting "'nameserver.c'" '(13854 characters)'
  150. if test -f 'nameserver.c'
  151. then
  152.     echo shar: will not over-write existing file "'nameserver.c'"
  153. else
  154. sed 's/^X//' << \SHAR_EOF > 'nameserver.c'
  155. X#ifndef lint
  156. X  static char *RCSid = "$Header: nameserver.c,v 2.3.1 88/02/26 jerry Rel $";
  157. X#endif
  158. X
  159. X/* nameserver --
  160. X   Use the IEN 116 protocol to respond to nameserver requests.
  161. X
  162. X   Modified by Jerry Aguirre.  21Mar1988
  163. X   Count in header does not include header bytes.  Added a "glob"
  164. X   capability so "*" returns all host names.  Removed fatal abort if no
  165. X   tty so daemon can be started from rc.local.
  166. X
  167. X   Written by Michael I. Bushnell.
  168. X   Copyright (c) 1987 Michael I. Bushnell
  169. X   You are hereby granted permission to use this program however you wish,
  170. X   including copying and distribution.  However, you are obligated not to sell
  171. X   it or any part of it.  Anyone who obtains this program receives the right
  172. X   to do the same.  This statement may not be removed from this program.
  173. X*/
  174. X
  175. X/*
  176. X * $Source: /u1/staff/mike/src/nameserver/RCS/nameserver.c,v $
  177. X * $Revision: 2.3 $
  178. X * $Date: 87/06/24 15:02:59 $
  179. X * $State: Rel $
  180. X * $Author: mike $
  181. X * $Locker:  $
  182. X * $Log:    nameserver.c,v $
  183. X * Revision 2.3.1 88/02/26 Jerry Aguirre
  184. X * Modified to work with Bridge terminal server version 1300.  The field
  185. X * size doesn't include the 2 byte header.  Also added a glob capability
  186. X * so '*' or 'xyz*' works.  The '*' may not return all hosts because the
  187. X * sendto limits the size I can send.
  188. X *
  189. X * Revision 2.3  87/06/24  15:02:59  mike
  190. X * Final preparations for release.  Addeed Copyright.
  191. X * 
  192. X * Revision 2.2  87/06/24  14:54:29  mike
  193. X * de-lintified.  Lint, stupidly, doesn't pick up the definition of h_errno f
  194. X * from libc.a.  Sigh.  Prepared for release.
  195. X * 
  196. X * Revision 2.1  87/06/24  14:48:14  mike
  197. X * Better comments.
  198. X * 
  199. X * Revision 2.0  87/06/23  16:55:03  mike
  200. X * Split it up into different functions.
  201. X * 
  202. X * Revision 1.9  87/06/23  16:14:09  mike
  203. X * Added stuff to divorce process from shell and control terminal.
  204. X * 
  205. X * Revision 1.8  87/06/19  16:59:36  mike
  206. X * Uses syslog instead of perror.
  207. X * Lots of symbolic constants.
  208. X * 
  209. X * Revision 1.7  87/06/19  14:43:49  mike
  210. X * Fixed bug... need to initialize addrlen to sizeof(hisname).
  211. X * 
  212. X * Revision 1.6  87/06/16  16:08:04  mike
  213. X * Changed all "sizeof (hisaddr)" to "addrlen."
  214. X * Still a bug...the last sendto is returning EINVAL???
  215. X * 
  216. X * Revision 1.5  87/06/16  15:57:07  mike
  217. X * Actually...you need to return the raw bytes.  So I changed it back.
  218. X * Also added bookoo error checking.
  219. X * 
  220. X * Revision 1.4  87/06/15  13:50:22  mike
  221. X * Fixed bug...need to cast the argument of inet_ntoa into a struct in_addr.
  222. X * 
  223. X * Revision 1.3  87/06/08  14:16:56  mike
  224. X * Uses a PORT number instead of system chosen default...now its 5001.
  225. X * 
  226. X * Revision 1.2  87/06/08  14:10:33  mike
  227. X * Now it compiles.
  228. X * 
  229. X * Revision 1.1  87/06/08  13:42:20  mike
  230. X * Initial revision
  231. X * 
  232. X */
  233. X
  234. X#include <sys/file.h>
  235. X#include <sgtty.h>
  236. X
  237. X#include <signal.h>
  238. X#include <syslog.h>
  239. X
  240. X#include <sys/types.h>
  241. X#include <sys/socket.h>
  242. X#include <netinet/in.h>
  243. X#include <netdb.h>
  244. X
  245. X#include <stdio.h>
  246. X#include <ctype.h>
  247. X
  248. X#include "ien116.h"
  249. X
  250. X/* Generic constants */
  251. X#define BUFLEN 512        /* Length of I/O buffers */
  252. X#define RBUFLEN 1400        /* Length of glob reply buffer */
  253. X            /* note that there is a limit on size of sendto */
  254. X#define DEF_PROTO 0        /* Use default protocol */
  255. X#define NO_FLAGS 0        /* No flags on recvfrom/sendto */
  256. X
  257. X/* Message lengths */
  258. X#define RET_MSG_LEN 6        /* Length of what we add to buf */
  259. X#define ERR_MSG_LEN 3        /* Length of error messages */
  260. X
  261. Xchar buf[BUFLEN];        /* Input/Output buffer */
  262. Xextern int errno, h_errno;
  263. Xextern char *sys_errlist[];
  264. X
  265. Xint debug;
  266. X
  267. Xmain(argc, argv) int argc; char *argv[];
  268. X{
  269. X  int sock;            /* Datagram socket */
  270. X  struct sockaddr_in hisname;    /* Address of requestor */
  271. X  int addrlen;            /* Length of his address */
  272. X  struct hostent *hp, *gethostbyname();    /* Host inquired of */
  273. X  char *name;            /* Name of the machine requested */
  274. X  int msglen;            /* Length of the message received */
  275. X  char *nameloc();
  276. X  int arg, i;
  277. X
  278. X  for (arg = 1; arg < argc; arg++) {
  279. X    if (argv[arg][0] == '-') {
  280. X      for (i = 1; argv[arg][i]; i++) {
  281. X    switch (argv[arg][i]) {
  282. X    case 'd':
  283. X      if (isdigit(argv[arg][i+1])) {
  284. X        debug = atoi(&argv[arg][i+1]);
  285. X        break;
  286. X      } else debug = 1;
  287. X      continue;
  288. X
  289. X    default:
  290. X      fprintf(stderr, "nameserver: unknown option \'-%c\'.\n",
  291. X                        argv[arg][i]);
  292. X    }
  293. X    break;
  294. X      }
  295. X    } else {
  296. X      fprintf(stderr, "nameserver: unexpected argument \"%s\".\n",
  297. X                        argv[arg]);
  298. X    }
  299. X  }
  300. X
  301. X  if (!debug) setupsig();    /* Set up signal handling */
  302. X  setuplog();            /* Set up the syslog connection */
  303. X  if (!debug) divorce();    /* Divorce ourselves from terminal and shell */
  304. X  sock = makesocket();        /* make and bind the socket */
  305. X  addrlen = sizeof(hisname);    
  306. X
  307. X  /* Main loop */
  308. X restart:
  309. X  while (1)
  310. X    {
  311. X      /* Read a message */
  312. X      msglen = recvfrom(sock, buf, BUFLEN - RET_MSG_LEN,
  313. X            NO_FLAGS, (struct sockaddr *)&hisname, &addrlen);
  314. X      if (debug) fprintf(stderr, "nameserver: got a request\n");
  315. X      if (msglen == -1)
  316. X    {
  317. X      syslog(LOG_ERR, "Error on incoming message: %s\n", 
  318. X         sys_errlist[errno]);
  319. X      if (debug) fprintf(stderr, "Error on incoming message: %s\n", 
  320. X         sys_errlist[errno]);
  321. X      goto restart;
  322. X    }
  323. X
  324. X      /* Find the name */
  325. X      name = nameloc(buf, BUFLEN, msglen, &hisname, addrlen, sock);
  326. X      if ((int) name == -1) {
  327. X    if (debug) fprintf(stderr, "nameserver: namelog() returned -1\n");
  328. X    goto restart;
  329. X      }
  330. X
  331. X      if (isglob(name)) {
  332. X      if (debug) fprintf(stderr, "nameserver: looking up pattern \"%s\".\n",
  333. X                            name);
  334. X      doglob(name, &hisname, addrlen, sock);
  335. X      goto restart;
  336. X      }
  337. X
  338. X      if (debug) fprintf(stderr, "nameserver: looking up host \"%s\".\n",
  339. X                            name);
  340. X      /* Get the host entry */
  341. X      if ((hp = gethostbyname(name))== NULL)
  342. X    {
  343. X      /* Send error message */
  344. X      buf[msglen] = ERR;    
  345. X      buf[msglen+1] = ERR_MSG_LEN - 2;
  346. X      if (h_errno == HOST_NOT_FOUND ||
  347. X          h_errno == TRY_AGAIN ||
  348. X          h_errno == NO_ADDRESS) 
  349. X        buf[msglen+2] = HOST_UNK; 
  350. X      else
  351. X        buf[msglen+2] = UNK_ERR; 
  352. X      if (sendto(sock, buf, msglen+ERR_MSG_LEN, NO_FLAGS, 
  353. X             (struct sockaddr *)&hisname, addrlen)==-1)
  354. X        {
  355. X          syslog(LOG_ERR, "Error sending error 3: %s\n", sys_errlist[errno]);
  356. X          goto restart;
  357. X        }  
  358. X    }
  359. X      else
  360. X    {
  361. X      /* Send the reply */
  362. X      buf[msglen] = ADDR_ANS;
  363. X      buf[msglen+1] = RET_MSG_LEN - 2;
  364. X      buf[msglen+2] = hp->h_addr_list[0][0];
  365. X      buf[msglen+3] = hp->h_addr_list[0][1];
  366. X      buf[msglen+4] = hp->h_addr_list[0][2];
  367. X      buf[msglen+5] = hp->h_addr_list[0][3];
  368. X
  369. X      if (debug) fprintf(stderr, "nameserver: return IP %d.%d.%d.%d\n",
  370. X                hp->h_addr_list[0][0] & 0xff,
  371. X                hp->h_addr_list[0][1] & 0xff,
  372. X                hp->h_addr_list[0][2] & 0xff,
  373. X                hp->h_addr_list[0][3] & 0xff);
  374. X
  375. X      if (sendto(sock, buf, msglen+RET_MSG_LEN, NO_FLAGS, 
  376. X             (struct sockaddr *)&hisname, addrlen)==-1)
  377. X        {
  378. X          syslog(LOG_ERR, "Error sending reply: %s\n", sys_errlist[errno]);
  379. X          goto restart;
  380. X        }
  381. X    }
  382. X    }
  383. X}
  384. X
  385. X
  386. X/* setupsig -- Set all signals to be ignored.  Those which cannot be ignored
  387. X   will be left at the default. */
  388. Xsetupsig()
  389. X{
  390. X  int i;            /* Index of signals */
  391. X  
  392. X  for (i=0; i < NSIG; ++i)
  393. X    (void) signal(i, SIG_IGN);
  394. X}
  395. X  
  396. X
  397. X/* setuplog -- set up the syslog connection */
  398. Xsetuplog()
  399. X{
  400. X  openlog("nameserver", LOG_PID | LOG_CONS, LOG_DAEMON);
  401. X}
  402. X
  403. X
  404. X/* divorce -- Divorce ourselves from the terminal and the shell */
  405. Xdivorce()
  406. X{
  407. X  int term;            /* Terminal filed */
  408. X
  409. X  /* First the shell */
  410. X  switch(fork()) 
  411. X    {
  412. X    case -1:
  413. X      syslog(LOG_CRIT, "Cannot fork: %s\n", sys_errlist[errno]);
  414. X      exit(1);
  415. X      break;
  416. X    case 0:
  417. X      break;
  418. X    default:
  419. X      exit(0);
  420. X      break;
  421. X    }
  422. X
  423. X  /* Now the files */
  424. X  /* POTENTIAL BUG-- ASSUMES THAT THE TERMINAL IS ONLY OPEN ON FILEDS 0,1,2 */
  425. X  (void) close (0);
  426. X  (void) close (1);
  427. X  (void) close (2);
  428. X  /* Now the terminal */
  429. X  /* if started from rc.local, crontab, etc. there is no tty */
  430. X  if ((term = open("/dev/tty", O_RDWR, 0)) >= 0)
  431. X    {
  432. X      if (ioctl(term, TIOCNOTTY, (char *) 0) == -1)
  433. X    {
  434. X      syslog(LOG_CRIT, "Cannot divorce from control terminal: %s\n", 
  435. X         sys_errlist[errno]);
  436. X      exit(1);
  437. X    }
  438. X      (void) close(term);
  439. X    }
  440. X}
  441. X
  442. X
  443. X/* makesocket -- return the filed of a new bound socket */
  444. Xmakesocket()
  445. X{
  446. X  int sock;            /* Socket */
  447. X  struct sockaddr_in ourname;    /* Our name */
  448. X
  449. X  /* create the socket */
  450. X  sock = socket(AF_INET, SOCK_DGRAM, DEF_PROTO);
  451. X  if (sock < 0)
  452. X    {
  453. X      syslog(LOG_CRIT, "Error opening socket: %s\n", sys_errlist[errno]);
  454. X      exit(1);
  455. X    }
  456. X  ourname.sin_family = AF_INET;
  457. X  ourname.sin_port = htons((u_short)PORT);
  458. X  ourname.sin_addr.s_addr = INADDR_ANY;
  459. X  if (bind(sock, &ourname, sizeof(ourname)))
  460. X
  461. X    {
  462. X      syslog(LOG_CRIT, "Error binding socket: %s\n", sys_errlist[errno]);
  463. X      exit(1);
  464. X    }
  465. X  return sock;
  466. X}  
  467. X
  468. X
  469. X/* nameloc -- return the address of a null-terminated string which is the
  470. X   name to be looked up.  Report syntax errors to reportto through sock.
  471. X   If an error occurs, return (char *) -1.  If an error occurs, buf will be 
  472. X   changed. */
  473. Xchar *
  474. Xnameloc(buf, buflen, msglen, reportto, addrlen, sock)
  475. X     char *buf;            /* Buffer holding the request */
  476. X     int buflen,        /* Length of the buffer */
  477. X       msglen,            /* Length of the message in the buffer */
  478. X       sock,            /* Socket for error replies */
  479. X       addrlen;            /* Length of reportto */
  480. X     struct sockaddr_in *reportto; /* Who we report errors to */
  481. X{
  482. X  char *name;            /* Address of the name */
  483. X  int code;            /* Type of request */
  484. X
  485. X  buf[msglen] = '\0';
  486. X  /* Check type */      
  487. X  code = buf[0];
  488. X  if (code != ADDR_REQ)
  489. X    if (code !=ADDR_ANS && code !=ERR)
  490. X      {
  491. X    /* Send error message */
  492. X    buf[0] = ERR;    
  493. X    buf[1] = ERR_MSG_LEN - 2;
  494. X    buf[2] = SYNT_ERR;
  495. X    if (sendto(sock, buf, ERR_MSG_LEN, NO_FLAGS, 
  496. X           (struct sockaddr *)&reportto, addrlen)==-1)
  497. X      {
  498. X        syslog(LOG_ERR, "Error sending error 0: %s\n", sys_errlist[errno]);
  499. X        return (char *) -1;
  500. X      }        
  501. X      }
  502. X    else
  503. X      return (char *) -1;
  504. X  
  505. X  /* Put name at the start of a null-terminated string */
  506. X  if (buf[2]!='!')
  507. X    name=buf+2;
  508. X  else
  509. X    {
  510. X      for(name=buf+2; *name!='!'; ++name)
  511. X    if (name-buf >= buflen)
  512. X      {            
  513. X        /* Send error packet */
  514. X        buf[0] = ERR;
  515. X        buf[1] = ERR_MSG_LEN - 2;
  516. X        buf[2] = SYNT_ERR;
  517. X        if (sendto(sock, buf, ERR_MSG_LEN, NO_FLAGS, 
  518. X               (struct sockaddr *)&reportto, addrlen)==-1)
  519. X          {
  520. X        syslog(LOG_ERR, "Error sending error 1: %s\n", 
  521. X               sys_errlist[errno]);
  522. X        return (char *) -1;
  523. X          }
  524. X      }
  525. X      for(++name; *name!='!'; ++name)
  526. X    if (name-buf >= buflen)
  527. X      {            
  528. X        /* Send error packet */
  529. X        buf[0] = ERR;
  530. X        buf[1] = ERR_MSG_LEN - 2;
  531. X        buf[2] = SYNT_ERR;
  532. X        if (sendto(sock, buf, ERR_MSG_LEN, NO_FLAGS, 
  533. X               (struct sockaddr *)&reportto, addrlen)==-1)
  534. X          {
  535. X        syslog(LOG_ERR, "Error sending error 2: %s\n", 
  536. X               sys_errlist[errno]);
  537. X        return (char *) -1;
  538. X          }
  539. X      }
  540. X      ++name;
  541. X    }
  542. X  return name;
  543. X}
  544. X
  545. Xint
  546. Xisglob(s) char *s; /* true if string s has pattern characters */
  547. X{
  548. X    while (*s) {
  549. X    switch (*s++) {
  550. X    case '*': return 1;
  551. X    }
  552. X    }
  553. X    return 0;
  554. X}
  555. X
  556. X/* check all hosts against pattern 's'.  To reduce clutter only the
  557. X * primary host name is checked, aliases are ignored.
  558. X */
  559. Xdoglob(s, reportto, addrlen, sock)
  560. X    char *s;            /* string containing pattern */
  561. X    struct sockaddr_in *reportto; /* Who we report errors to */
  562. X    int addrlen;        /* Length of reportto */
  563. X    int sock;            /* Socket for error replies */
  564. X{
  565. X    struct hostent *hp, *gethostent();
  566. X    int i, l, n;
  567. X    char buf[RBUFLEN];        /* Output buffer */
  568. X
  569. X    if (s[0] == '\0') { /* null pattern is illegal */
  570. X    reterror(ADDR_REQ, s, SYNT_ERR, reportto, addrlen, sock);
  571. X    return 0;
  572. X    }
  573. X    sethostent(1);
  574. X    i = 0; n = 0;
  575. X    while ((i < RBUFLEN) && (hp = gethostent())) {
  576. X    if (requ(s, hp->h_name)) { /* we found a match */
  577. X        n++;
  578. X        l = strlen(hp->h_name);
  579. X        if (l > 255) l = 255;
  580. X        if ((i + 2 + l + 2 + 4) >= RBUFLEN) break;
  581. X        buf[i++] = ADDR_REQ;
  582. X        buf[i++] = l;
  583. X        strncpy(buf+i, hp->h_name, l);
  584. X        i += l;
  585. X        buf[i++] = ADDR_ANS;
  586. X        buf[i++] = 4;
  587. X        buf[i++] = hp->h_addr_list[0][0];
  588. X        buf[i++] = hp->h_addr_list[0][1];
  589. X        buf[i++] = hp->h_addr_list[0][2];
  590. X        buf[i++] = hp->h_addr_list[0][3];
  591. X    }
  592. X    }
  593. X    endhostent();
  594. X    if (n == 0) {
  595. X    reterror(ADDR_REQ, s, HOST_UNK, reportto, addrlen, sock);
  596. X    return 1;
  597. X    }
  598. X    if (i > 0) {
  599. X    if (sendto(sock, buf, i, NO_FLAGS, 
  600. X         (struct sockaddr *)reportto, addrlen)==-1) {
  601. X        syslog(LOG_ERR, "Error sending reply: %s\n", sys_errlist[errno]);
  602. X        return 0;
  603. X    }
  604. X    }
  605. X    return 1;
  606. X}
  607. X
  608. Xreterror(rcode, rs, ecode, reportto, addrlen, sock)
  609. X     int rcode;            /* type of request containing error */
  610. X     char *rs;            /* string for above request */
  611. X     int ecode;            /* error code to return */
  612. X     struct sockaddr_in *reportto; /* Who we report errors to */
  613. X     int addrlen;        /* Length of reportto */
  614. X     int sock;            /* Socket for error replies */
  615. X{
  616. X    int i;
  617. X    char buf[BUFLEN];        /* Output buffer */
  618. X
  619. X    buf[0] = rcode;
  620. X    i = strlen(rs);
  621. X    if (i > 255) i = 255;
  622. X    buf[1] = i;
  623. X    strncpy(buf+2, rs, i);
  624. X    i += 2;
  625. X    buf[i++] = ERR;
  626. X    buf[i++] = 1;
  627. X    buf[i++] = ecode;
  628. X    if (sendto(sock, buf, i, NO_FLAGS, 
  629. X           (struct sockaddr *)&reportto, addrlen)==-1) {
  630. X    syslog(LOG_ERR, "Error sending error %d: %s\n",
  631. X                    ecode, sys_errlist[errno]);
  632. X    return 0;
  633. X    }        
  634. X    return 1;
  635. X}
  636. X
  637. X/* Compare pattern 'p' to string 's'.  Pattern can contain '*'
  638. X * characters that will match 0 or more characters in string.  Otherwise
  639. X * the strings are compared on a character by character basis.  Returns
  640. X * non-zero for a match.
  641. X */
  642. Xint
  643. Xrequ(p, s) register char *p, *s;
  644. X{
  645. X    while (*p) {
  646. X    if (*p == '*') {
  647. X        do {
  648. X        if (requ(p+1, s)) return 1;    /* match */
  649. X        } while (*s++);
  650. X        return 0;    /* no match */
  651. X    }
  652. X    else if (*s == '\0') return 0; /* no match */
  653. X    else if (*p != *s) return 0; /* no match */
  654. X    p++; s++;    /* they match so far */
  655. X    }
  656. X    if (*s) return 0; /* no match */
  657. X    return 1;    /* reached end of both strings, match */
  658. X}
  659. SHAR_EOF
  660. if test 13854 -ne "`wc -c < 'nameserver.c'`"
  661. then
  662.     echo shar: error transmitting "'nameserver.c'" '(should have been 13854 characters)'
  663. fi
  664. fi # end of overwriting check
  665. echo shar: extracting "'driver.c'" '(4768 characters)'
  666. if test -f 'driver.c'
  667. then
  668.     echo shar: will not over-write existing file "'driver.c'"
  669. else
  670. sed 's/^X//' << \SHAR_EOF > 'driver.c'
  671. X#ifndef lint
  672. X  static char *RCSid = "$Header: driver.c,v 1.5.1 88/02/26 jerry Rel $";
  673. X#endif
  674. X
  675. X/* driver --
  676. X   drive the IEN 116 nameserver.
  677. X
  678. X   Modified by Jerry Aguirre.  21Mar1988
  679. X   First argument is name of server to use.  Other arguments are names
  680. X   to find.  More extensive display of responses.
  681. X
  682. X   Written by Michael I. Bushnell.
  683. X   Copyright (c) 1987 Michael I. Bushnell
  684. X   You are hereby granted permission to use this program however you wish, 
  685. X   including copying and distribution.  However, you are obligated not to sell
  686. X   it or any part of it.  Anyone who obtains this program receives the right
  687. X   to do the same.  This statement may not be removed from this program.
  688. X*/
  689. X
  690. X/*
  691. X * $Source: /u1/staff/mike/src/nameserver/RCS/driver.c,v $
  692. X * $Revision: 1.5 $
  693. X * $Date: 87/06/24 15:02:38 $
  694. X * $State: Rel $
  695. X * $Author: mike $
  696. X * $Locker:  $
  697. X * $Log:    driver.c,v $
  698. X * Revision 1.5.1 88/02/26 Jerry Aguirre <jerry@olivetti.com>
  699. X * Field sizes don't include 2 byte header.  First arg is now name
  700. X * of server to request from.  Structure of response message is displayed.
  701. X *
  702. X * Revision 1.5  87/06/24  15:02:38  mike
  703. X * Prepared for final release.  Added Copyright.
  704. X * 
  705. X * Revision 1.4  87/06/19  17:00:05  mike
  706. X * More toying around.
  707. X * 
  708. X * Revision 1.3  87/06/19  14:44:13  mike
  709. X * Toyed around.
  710. X * 
  711. X * Revision 1.2  87/06/15  13:50:51  mike
  712. X * Changed the host it asks for
  713. X * 
  714. X * Revision 1.1  87/06/12  13:42:29  mike
  715. X * Initial revision
  716. X * 
  717. X */
  718. X
  719. X#include <sys/types.h>
  720. X#include <sys/socket.h>
  721. X#include <netinet/in.h>
  722. X#include <stdio.h>
  723. X#include <netdb.h>
  724. X
  725. X#include "ien116.h"
  726. X
  727. X#define BUFLEN 2000
  728. Xchar buf[BUFLEN];
  729. X
  730. X/* Driver for the IEN 116 nameserver */
  731. X
  732. Xmain(argc, argv) int argc; char *argv[];
  733. X{
  734. X  int sock;            /* Datagram socket */
  735. X  struct sockaddr_in from;    /* Where we got the reply from */
  736. X  struct sockaddr_in server;    /* Server's address */
  737. X  struct sockaddr_in ourname;    /* Our address */
  738. X  int addrlen;            /* Address length */
  739. X  int c,i;            /* Generic counters */
  740. X  int arg;
  741. X  struct hostent *hp, *gethostbyname();    /* Host inquired of */
  742. X  char *hostname;
  743. X  int j, k;
  744. X  int code, length;
  745. X  
  746. X  if (argc < 3) {
  747. X    printf("usage: driver server name ...");
  748. X    exit(1);
  749. X  }
  750. X
  751. X  sock = socket(AF_INET, SOCK_DGRAM, 0);
  752. X  if (sock < 0)
  753. X    {
  754. X      perror("driver: opening socket");
  755. X      exit (1);
  756. X    }
  757. X  ourname.sin_family = AF_INET;
  758. X  ourname.sin_port = 0;
  759. X  ourname.sin_addr.s_addr = INADDR_ANY;
  760. X  if (bind(sock, (struct sockaddr *)&ourname, sizeof(ourname)))
  761. X    {
  762. X      perror("driver: binding socket");
  763. X      exit(1);
  764. X    }
  765. X  
  766. X  /* server.sin_family = AF_INET; */
  767. X  server.sin_port = htons((u_short)PORT);
  768. X  /* server.sin_addr.s_addr = INADDR_ANY; */
  769. X  server.sin_addr.s_addr = INADDR_ANY;
  770. X  hp = gethostbyname(argv[1]);
  771. X  if (hp) {
  772. X      server.sin_family = hp->h_addrtype;
  773. X#ifndef    NOT43
  774. X      bcopy(hp->h_addr_list[0], (caddr_t)&server.sin_addr,
  775. X          hp->h_length);
  776. X#else    NOT43
  777. X      bcopy(hp->h_addr, (caddr_t)&server.sin_addr,
  778. X          hp->h_length);
  779. X#endif    NOT43
  780. X      hostname = hp->h_name;
  781. X  } else {
  782. X      printf("%s: unknown host\n", argv[1]);
  783. X      exit(1);
  784. X  }
  785. X
  786. X  for (arg = 2; arg < argc; arg++) {
  787. X    i = strlen(argv[arg]);
  788. X    buf[0] = ADDR_REQ;        /* Code for request */
  789. X    buf[1] = i;            /* Length of message */
  790. X    strcpy(buf+2, argv[arg]);    /* name */
  791. X
  792. X    if (sendto(sock, buf, i+2, 0, (struct sockaddr *)&server, sizeof(server))==-1)
  793. X      {
  794. X    perror("driver: sending message");
  795. X    exit(1);
  796. X      }
  797. X
  798. X    if ((c=recvfrom(sock, buf, BUFLEN, 0, (struct sockaddr *)&from, sizeof(from)))==-1)
  799. X      {
  800. X    perror("driver: getting message");
  801. X    exit(1);
  802. X      }
  803. X
  804. X    printf("response for \"%s\" (%d bytes):\n", argv[arg], c);
  805. X    for(i=0;(i + 1) <c;) {
  806. X      putchar('\t');
  807. X      code = buf[i++] & 0xff;
  808. X      length = buf[i++] & 0xff;
  809. X      switch (code) {
  810. X      case ADDR_REQ:
  811. X        printf("ADDR_REQ: length %d \"", length);
  812. X    for (k = 0; k < length; k++) {
  813. X      if ((buf[i+k] >= ' ') && (buf[i+k] <= '~')) putchar(buf[i+k]);
  814. X      else printf("\\%3.3o", buf[i+k] & 0xff);
  815. X    }
  816. X    printf("\"");
  817. X    break;
  818. X      case ADDR_ANS:
  819. X        printf("ADDR_ANS: length %d", length);
  820. X    for (k = 0; k < length; k++) {
  821. X      if (k == 0) printf(" %d", buf[i+k] & 0xff);
  822. X      else        printf(".%d", buf[i+k] & 0xff);
  823. X    }
  824. X    break;
  825. X      case ERR:
  826. X        printf("ERR: length %d", length);
  827. X    for (k = 0; k < length; k++) {
  828. X      j = buf[i+k] & 0xff;
  829. X      printf(" error code %d", j);
  830. X      switch (j) {
  831. X          case UNK_ERR:
  832. X        printf(" UNK_ERR");
  833. X          break;
  834. X          case HOST_UNK:
  835. X        printf(" HOST_UNK");
  836. X          break;
  837. X          case SYNT_ERR:
  838. X        printf(" SYNT_ERR");
  839. X          break;
  840. X          default:
  841. X        printf("????");
  842. X      }
  843. X    }
  844. X    break;
  845. X      default:
  846. X        printf("Unknown response code 0x%x, length %d.", buf[i] & 0xff, length);
  847. X    break;
  848. X      }
  849. X      i += length;
  850. X      printf("\n");
  851. X    }
  852. X  }    /* for each arg */
  853. X}
  854. SHAR_EOF
  855. if test 4768 -ne "`wc -c < 'driver.c'`"
  856. then
  857.     echo shar: error transmitting "'driver.c'" '(should have been 4768 characters)'
  858. fi
  859. fi # end of overwriting check
  860. #    End of shell archive
  861. exit 0
  862.  
  863.